package model.aop.demo.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;


/**
 *
 */
// 开启注解切面编程

//切面类 (代理类)
@Aspect
@Component
@Order(1)
public class MyAspect {
    //切面  定义切入点  切入点表达式
    // execution 用于匹配执行的方法
    // 切入表达式
    // * ..

    //  方法的修饰符  返回值类型   方法所在的类的路径  方法(参数列表)
    @Pointcut("execution(public * model.aop.demo.service.*Service.*(..))")
    public void pointcut() {
    }

    //重要的属性  value   切入点表达式  获取切点方法
    @Before(value = "pointcut()")
    public void before() {
        System.out.println("MyAspect 2.核心方法执行之前执行的操作");
    }

    @AfterReturning(value = "pointcut()")
    public void afterReturning() {
        System.out.println("4.在方法正常的返回值之后");
    }

    // 注意 在程序中能处理异常 如果处理立场 异常通知是接受不到的
    @AfterThrowing(value = "pointcut()", throwing = "ex")
    public void afterThrowing(Exception ex) {
        System.out.println(ex.getMessage());
        System.out.println("4.核心方法抛出异常后执行");
    }

    // 最终通知  后置通知
    @After("pointcut()")
    public void after() {
        System.out.println("5.最终通知");
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) {
        Object proceed = null;
        try {
            System.out.println("1.环绕通知----核心方法之前");
            proceed = pjp.proceed();
            System.out.println("6.环绕通知----核心方法后");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return proceed;
    }


}
